home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / SDKs / Word Services SDK 1.0.6 / Writeswell Jr 1.2.1 Sources ƒ / Writeswell Jr. Source / ServiceDialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-11  |  10.2 KB  |  455 lines  |  [TEXT/KAHL]

  1. /* ServiceMgr.c
  2.  * Handle the Services menu in Writeswell, Jr.
  3.  * ©1992 Working Software, Inc.
  4.  * This source code is copyrighted.  Permission is granted to use the Word Services
  5.  * portion of the Writeswell Jr. source code in your own programs, but you 
  6.  * may not distribute the Writeswell Jr. word-processor code as a 
  7.  * commercial product.  If you modify the code, please do not call it 
  8.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  9.  * program and don’t have to deal with a number of different versions with 
  10.  * who-knows-what going on in the code.
  11.  * 
  12.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  13.  * 19 Apr 92 Mike Crawford
  14.  */
  15.  
  16. #include <Aliases.h>
  17. #include <AppleEvents.h>
  18. #include "TestBed.h"
  19. #include "TBConstants.h"
  20. #include "Gripe.h"
  21. #include "Prefs.h"
  22. #include "ServiceMgr.h"
  23. #include "TBGlobals.h"
  24. #include "ServiceDialog.h"
  25. #include "OutlineButton.h"
  26. #include "Key.h"
  27. #include "InitMenu.h"
  28.  
  29. pascal void ServiceListProc( DialogPtr theDialog, short item );
  30. OSErr MakeServiceList( DialogPtr dPtr );
  31. OSErr FillServiceList( ListHandle lHdl );
  32. pascal Boolean RemoveDlogProc( DialogPtr theDialog,
  33.                                 EventRecord *eventPtr,
  34.                                 short *itemPtr );
  35. void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl );
  36. void RemoveSelectedServices( ListHandle lHdl );
  37.  
  38. void RemoveServices( void )
  39. {
  40.     DialogPtr    servDlg;
  41.     short        item;
  42.     short        kind;
  43.     Handle        h;
  44.     Rect        r;
  45.     ListHandle    lHdl;
  46.     OSErr        err;
  47.     UserItemUPP    outlineUPP;
  48.     UserItemUPP    serviceListUPP;
  49.     
  50.     // Anywhere we use a dialog we must take extra care that UPP's are
  51.     // set up properly on the PowerPC.  Because the user item proc is cast
  52.     // as a handle in SetDItem, there is no way for the compiler to know that
  53.     // we are passing in a pointer to a function rather than a pointer to a
  54.     // routine descriptor.  One finds out quickly when running the program - it
  55.     // always crashes when displaying a dialog that has a user item.
  56.     
  57.     servDlg = GetNewDialog( rRemoveDialogID, (Ptr)NULL, (WindowPtr)-1 );
  58.     if ( !servDlg )
  59.         return;
  60.     
  61.     /* Set up a user proc to draw the default outline */
  62.  
  63.     GetDItem( servDlg, kRDDefUser, &kind, &h, &r );
  64.     
  65.     outlineUPP = NewUserItemProc( OutlineButton );
  66.     if ( !outlineUPP )
  67.         return;                // STUB should report an error 
  68.  
  69.     SetDItem( servDlg, kRDDefUser, kind, (Handle)outlineUPP, &r );
  70.  
  71.     /* Set up the user proc to draw the service list */
  72.     GetDItem( servDlg, kRDListUser, &kind, &h, &r );
  73.     
  74.     serviceListUPP = NewUserItemProc( ServiceListProc );
  75.     if ( !serviceListUPP )
  76.         return;                // STUB should report an error 
  77.  
  78.     SetDItem( servDlg, kRDListUser, kind, (Handle)serviceListUPP, &r );
  79.  
  80.     err = MakeServiceList( servDlg );
  81.     if ( err ){
  82.         Gripe( "\pMakeServiceList failed" );
  83.         return;
  84.     }
  85.  
  86.     lHdl = (ListHandle)GetWRefCon( servDlg );
  87.  
  88.     err = FillServiceList( lHdl );
  89.     if ( err ){
  90.         Gripe( "\pFillServiceList failed" );
  91.         return;    
  92.     }
  93.  
  94.     SetPort( servDlg );
  95.  
  96.     LDoDraw( true, lHdl );
  97.  
  98.     HiliteRemoveButton( servDlg, lHdl );
  99.  
  100.     do {
  101.         ModalDialog( (ModalFilterUPP)RemoveDlogProc, &item );
  102.         
  103.         if ( item == kRDRemove ){
  104.             RemoveSelectedServices( lHdl );
  105.             HiliteRemoveButton( servDlg, lHdl );
  106.         }
  107.  
  108.     } while ( item != kRDDone );
  109.     
  110.     LDispose( lHdl );
  111.  
  112. #ifdef GENERATINGCFM
  113.     DisposeRoutineDescriptor( outlineUPP );
  114.     DisposeRoutineDescriptor( serviceListUPP );
  115. #endif
  116.     
  117.     DisposDialog( servDlg );
  118.     
  119.     RebuildServiceMenu();
  120.     
  121.     return;
  122. }
  123.  
  124. pascal void ServiceListProc( DialogPtr theDialog, short item )
  125. {
  126.     Handle        itemHdl;
  127.     short        itemKind;
  128.     Rect        itemRect;
  129.     PenState    oldPenState;
  130.     ListHandle    lHdl;
  131.  
  132.     /* Get the user item rectangle */
  133.     GetDItem( theDialog, item, &itemKind, &itemHdl, &itemRect );
  134.  
  135.     /* Draw the frame around the list */
  136.     GetPenState( &oldPenState );
  137.     PenNormal();
  138.         
  139.     FrameRect( &itemRect );
  140.     
  141.     SetPenState( &oldPenState );
  142.     
  143.     /* Update the list itself */
  144.  
  145.     lHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
  146.     
  147.     LUpdate( ( (WindowPeek)theDialog )->port.visRgn, lHdl );
  148.  
  149.     return;
  150. }
  151.  
  152. OSErr MakeServiceList( DialogPtr dPtr )
  153. {
  154.     Handle        itemHdl;
  155.     short        itemKind;
  156.     Rect        itemRect;
  157.     Rect        listRect;
  158.     Rect        dataBounds;
  159.     Point        cellSize;
  160.     ListHandle    lHdl;
  161.  
  162.     /* Get the rect from the dialog user item.
  163.      * The user item exists in the DITL as a placeholder for us to get a rect
  164.      * from, and also to report hits on.
  165.      */
  166.     GetDItem( dPtr, kRDListUser, &itemKind, &itemHdl, &itemRect );
  167.     
  168.     /* Make room for the scroll bar.  This is outside of the rect that is passed to
  169.      * LNew.
  170.      * We use a copy of the rect so we don't change the real one in the dialog
  171.      */
  172.     
  173.     listRect = itemRect;                    /* Structure Assignment */
  174.     listRect.right -= kListScrollBarWidth;
  175.     InsetRect( &listRect, 1, 1 );            /* 1 pixel inside user item to allow outline */
  176.     
  177.     /* Set up the data bounds for a single column list,  with no initial elements */
  178.     SetRect( &dataBounds, 0, 0, 1, 0 );
  179.     
  180.     /* Use the default cell size */
  181.     cellSize.h = 0;
  182.     cellSize.v = 0;
  183.     
  184.     /* make the list */
  185.     lHdl = LNew( &listRect, &dataBounds, cellSize, kListTextProc,
  186.                             (WindowPtr) dPtr, false, false, false, true );
  187.  
  188.     if ( !lHdl || !*lHdl ){
  189.         Gripe( "\pLNew failed" );
  190.         return memFullErr;
  191.     }
  192.  
  193.     SetWRefCon( dPtr, (long)lHdl );
  194.  
  195.     /* Get the filenames for the list, and install them */
  196.     
  197.     return noErr;
  198. }
  199.  
  200. OSErr FillServiceList( ListHandle lHdl )
  201. {
  202.     WWJrPrefsHdl    prefHdl;
  203.     short            i;
  204.     short            servNum;
  205.     StringHandle    menuStrHdl;
  206.     short            curFile;
  207.     short            resID;
  208.     Cell            newCell;
  209.  
  210.     prefHdl = GetPrefHandle();
  211.     if ( !prefHdl ){
  212.         Gripe( "\pCannot get preferences handle" );
  213.         return resNotFound;
  214.     }
  215.  
  216.     curFile = CurResFile();
  217.     UseResFile( gPrefFileRefNum );
  218.  
  219.     servNum = 0;
  220.  
  221.     newCell.h = 0;
  222.  
  223.     for ( i = 0; i < kMaxServices; i++ ){
  224.         if ( (*prefHdl)->serviceType[ i ] != kNoService ){
  225.         
  226.             resID = kServiceBaseID + i;
  227.  
  228.             menuStrHdl = GetString( resID );
  229.             if ( !menuStrHdl ){
  230.                 Gripe( "\pCannot get string resource for service menu" );
  231.                 UseResFile( curFile );
  232.                 return resNotFound;
  233.             }
  234.             
  235.             newCell.v = servNum++;
  236.  
  237.             LAddRow( 1, 32767, lHdl );
  238.  
  239.             HLock( (Handle) menuStrHdl );
  240.             LSetCell( &( (*menuStrHdl)[1] ), (short)((*menuStrHdl)[0]), newCell, lHdl );
  241.             HUnlock( (Handle) menuStrHdl );
  242.  
  243.             ReleaseResource( (Handle) menuStrHdl );            
  244.         }
  245.     }
  246.  
  247.     UseResFile( curFile );
  248.     return noErr;
  249. }
  250.  
  251. pascal Boolean RemoveDlogProc( DialogPtr theDialog,
  252.                                 EventRecord *eventPtr,
  253.                                 short *itemPtr )
  254. {
  255.     Handle h;
  256.     short kind;
  257.     Rect listRect;
  258.     Point localPt;
  259.     ListHandle listHdl;
  260.  
  261.     switch( eventPtr->what ){
  262.         case keyDown:
  263.             switch( eventPtr->message & charCodeMask ){
  264.                 case enterKey:
  265.                 case retKey:
  266.                 case escKey:
  267.                     *itemPtr = kRDDone;        /* Take safe way out.  May not like this */
  268.                     return true;
  269.                     break;
  270.             }
  271.             break;
  272.         case mouseDown:
  273.             /* check if it's in the list.  Have to do this in the Proc so we can
  274.              * look at the event record
  275.              */
  276.  
  277.             GetDItem( theDialog, kRDListUser, &kind, &h, &listRect );
  278.  
  279.             localPt = eventPtr->where;
  280.             GlobalToLocal( &localPt );
  281.  
  282.             if ( PtInRect( localPt, &listRect ) ){
  283.  
  284.                 /* Work around a bug in the List Manager where if there are several
  285.                  * files selected, an unshifted click will not deselect the selected files
  286.                  */
  287.                 
  288.                 listHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
  289.  
  290.                 if ( ! (eventPtr->modifiers & shiftKey) &&
  291.                          !(eventPtr->modifiers & cmdKey) ){
  292.                     
  293.                 
  294.                     if ( PtInRect( localPt, &((*listHdl)->rView) ) ){
  295.                         Cell myCell;
  296.                         
  297.                         /* LDoDraw( false, listhdl ); */
  298.                         
  299.                         myCell.h = 0;
  300.                         myCell.v = 0;
  301.                         
  302.                         while ( LGetSelect( true, &myCell, listHdl ) ){
  303.                             LSetSelect( false, myCell, listHdl );
  304.                         }
  305.                         
  306.                         /* LDoDraw( true, listHdl ); */
  307.                     }
  308.                 }
  309.                 /* We presently don't care if they double-clicked */
  310.                 LClick( localPt, eventPtr->modifiers, listHdl );
  311.                 HiliteRemoveButton( theDialog, listHdl );
  312.             }
  313.             break;
  314.         case updateEvt:
  315.             LUpdate( ( (WindowPeek)theDialog )->port.visRgn,
  316.                 (ListHandle)GetWRefCon( (WindowPtr)theDialog ) );
  317.             break;
  318.     }
  319.  
  320.     return false;
  321. }
  322.  
  323. /* Dim or Hilite Remove button according to whether there is a selection */
  324.  
  325. void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl )
  326. {
  327.     Handle itemHdl;
  328.     short itemKind;
  329.     Rect itemRect;
  330.     Cell theCell;
  331.  
  332.     GetDItem( dPtr, kRDRemove, &itemKind, &itemHdl, &itemRect );
  333.     
  334.     theCell.h = 0;
  335.     theCell.v = 0;
  336.     
  337.     if ( LGetSelect( true, &theCell, lHdl ) ){
  338.         HiliteControl( (ControlHandle)itemHdl, 0 );
  339.     } else {
  340.         HiliteControl( (ControlHandle)itemHdl, 255 );
  341.     }
  342.  
  343.     return;
  344. }
  345.  
  346. void RemoveSelectedServices( ListHandle lHdl )
  347. {
  348.     WWJrPrefsHdl    prefHdl;
  349.     short            index;
  350.     short            servCount;
  351.     short            curFile;
  352.     short            resID;
  353.     short            iconResID;
  354.     Cell            nextCell;
  355.     Handle            menuStrHdl;
  356.     Handle            aliasHdl;
  357.     Handle            iconHdl;
  358.     short            itemNo;
  359.  
  360.     prefHdl = GetPrefHandle();
  361.     if ( !prefHdl ){
  362.         Gripe( "\pCannot get preferences handle" );
  363.         return;
  364.     }
  365.  
  366.     curFile = CurResFile();
  367.     UseResFile( gPrefFileRefNum );
  368.  
  369.     nextCell.h = 0;
  370.     nextCell.v = 0;
  371.         
  372.  
  373.     while ( LGetSelect( true, &nextCell, lHdl ) ){
  374.         
  375.         itemNo = nextCell.v + 1;
  376.  
  377.         /* We need to unselect the cell we just got so it won't be gotten repeatedly
  378.          * at the end 
  379.          */
  380.         
  381.         LSetSelect( false, nextCell, lHdl );
  382.  
  383.         index = 0;
  384.         servCount = 0;
  385.         
  386.         do {
  387.         
  388.             if ( (*prefHdl)->serviceType[ index++ ] != kNoService )
  389.                 servCount++;
  390.  
  391.         } while ( servCount < itemNo );
  392.  
  393.         index--;
  394.         
  395.         (*prefHdl)->serviceType[ index ] = kNoService;
  396.         
  397.         resID = kServiceBaseID + index;
  398.         
  399.         /* Remove the resource */
  400.         
  401.         menuStrHdl = GetResource( 'STR ', resID );
  402.         
  403.         if ( !menuStrHdl ){
  404.             Gripe( "\pFailed to get menu string in RemoveSelectedServices" );
  405.             UseResFile( curFile );
  406.             return;
  407.         }
  408.         
  409.         RmveResource( menuStrHdl );
  410.  
  411.         /* 1.1.1 MDC Fix memory leak */
  412.         
  413.         DisposHandle( menuStrHdl );
  414.  
  415.         aliasHdl = GetResource( rAliasType, resID );
  416.         
  417.         if ( !aliasHdl ){
  418.             Gripe( "\pFailed to get alias resource in RemoveSelectedServices" );
  419.             UseResFile( curFile );
  420.             return;
  421.         }
  422.         
  423.         RmveResource( aliasHdl );
  424.  
  425.         /* 1.1.1 MDC Fix memory leak */
  426.         
  427.         DisposHandle( aliasHdl );
  428.  
  429.         /* Remove the icon */
  430.  
  431.         iconResID = kMenuIconBaseID + index;
  432.         
  433.         iconHdl = GetResource( 'SICN', iconResID );
  434.         
  435.         /* It is permissible for there to be no icon resource */
  436.  
  437.         if ( iconHdl ){
  438.             RmveResource( iconHdl );
  439.  
  440.             /* 1.1.1 MDC Fix memory leak */
  441.             
  442.             DisposHandle( iconHdl );
  443.  
  444.         }
  445.  
  446.         LDelRow( 1, nextCell.v, lHdl );            /* Take item out of list */
  447.     }
  448.  
  449.     ChangedResource( (Handle) prefHdl );
  450.     WriteResource( (Handle) prefHdl );
  451.  
  452.     UseResFile( curFile );
  453.     return;
  454. }
  455.